package com.henry.extension.logging;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.action.Action;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.spi.ExtendedLogger;
import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;

public class DynamicAddLogger {
    private static final String datalogDir = "log";
    private static final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    private static final Configuration config = ctx.getConfiguration();

    public static Logger getLogger(String loggername) {
        if (!config.getLoggers().containsKey(loggername)) {
            synchronized (config) {
                addLogger(loggername);
            }
        }
        return LogManager.getLogger(loggername);

    }

    public static ExtendedLoggerWrapper getExLogger(String loggername) {
        if (!config.getLoggers().containsKey(loggername)) {
            synchronized (config) {
                addLogger(loggername);
            }
        }
        ExtendedLoggerWrapper loggerWrapper = new ExtendedLoggerWrapper((ExtendedLogger) LogManager.getLogger(loggername), loggername, null);
        return loggerWrapper;

    }

    public static void testLogPrint(String msg) {
        ExtendedLoggerWrapper loggerWrapper = getExLogger("log/test3");
        loggerWrapper.logIfEnabled(DynamicAddLogger.class.getName(), Level.TRACE, null, msg);

    }


    @SuppressWarnings({"rawtypes", "unchecked"})
    private static void addLogger(String loggerPathPrefix) {

        //创建一个展示的样式：PatternLayout，   还有其他的日志打印样式。
        Layout layout = PatternLayout.newBuilder()
                .withConfiguration(config).withPattern("%d{yyyy-MM-dd HH:mm:ss,SSS} %2p [%t] (%F:%L) - %m%n").build();

        //单个日志文件大小
        TriggeringPolicy tp = SizeBasedTriggeringPolicy.createPolicy("50M");
        CompositeTriggeringPolicy policyComposite = CompositeTriggeringPolicy.createPolicy(tp);


        Action[] actions = new Action[]{};

        @SuppressWarnings("deprecation")
        DefaultRolloverStrategy strategy = DefaultRolloverStrategy.createStrategy(
                "50", "1", null, null, actions, false, config);

        RollingFileAppender.Builder b = (RollingFileAppender.Builder)RollingFileAppender.newBuilder()
                .withFileName(loggerPathPrefix + ".log")
                .withFilePattern(loggerPathPrefix + ".%i.log")
                .withAppend(true)
                .withStrategy(strategy)
                .withName(loggerPathPrefix)
                .withPolicy(policyComposite)
                .withLayout(layout)
                .withConfiguration(config);
        RollingFileAppender appender = b.build();
        appender.start();
        config.addAppender(appender);

        AppenderRef ref = AppenderRef.createAppenderRef(loggerPathPrefix, null, null);
        AppenderRef[] refs = new AppenderRef[]{ref};
        LoggerConfig loggerConfig = LoggerConfig.createLogger(false,
                Level.TRACE, loggerPathPrefix, "true", refs, null, config, null);
        loggerConfig.addAppender(appender, null, null);
        config.addLogger(loggerPathPrefix, loggerConfig);
        ctx.updateLoggers();
    }


    public static void test1() {
        final Logger logger = LogManager.getRootLogger();
        long start = System.currentTimeMillis();
        for (int i = 1; i <= 100; i++) {
            new Thread(new Runnable() {
                public void run() {
                    for (int j = 1; j < 20000; j++) {
                        System.out.println("qwertyuiopasdfghjklzxcvbnm");
                    }
                }
            }).start();
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

}
